﻿#include "local.h"
#include "target.h"

int all_1=0,success=0;
Mat k = getStructuringElement(1, Size(5, 5));
 
int main()
{
    cout<<"请输入需要识别的装甲板的颜色（0为红色，1为蓝色）"
    cin >> mode;
    int mode = 1;//0为红色，1为蓝色

    Mat img, src, dst;
    vector<Mat> temp;
    vector<vector<Point>> contours;
    vector<light>  Light;
    vector<target> Target;

    VideoCapture video(0);
  	video.set(CAP_PROP_EXPOSURE, 0.008);
  	//video.set(CAP_PROP_FRAME_HEIGHT, 288);
  	//video.set(CAP_PROP_FRAME_WIDTH, 352);
  
  	while (cv::waitKey(1)!=27)
  	{
       all_1++;
  		video >> img;
       //img = imread("D:/test.png");

  	    int64 t = getTickCount();
  		src = img.clone();

  		fillContours(img,mode);
        
  		split(img, temp);
        dst = temp[2] * 1.5;
        dst -= temp[0] + temp[1];
  		
  		threshold(dst, dst, 100, 255, THRESH_BINARY);
  		findContours(dst, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);

        //cv::imshow("dst", dst);

        for (int i = 0; i < contours.size(); i++)
        {
            light temp(contours[i]);
            //cout << "relative_area_ratio:" << temp.relative_area_ratio << endl;
            //cout << "length_width_ratio:" << temp.length_width_ratio << endl;
            //cout << "approxPolyDP_count:" << temp.approxPolyDP_count << endl<<endl;

            if (temp.relative_area_ratio < 0.6 || temp.relative_area_ratio>1)
                continue;
            if (temp.length_width_ratio < 2 || temp.length_width_ratio>5)
                continue;
            if (temp.approxPolyDP_count < 2 || temp.approxPolyDP_count>5)
                continue;

            Light.push_back(temp);
            //drawContours(src, contours, i, Scalar(255, 0, 0), -1);
        }
        
        if (Light.size() < 2)
            goto label;

        for (int i = 0; i < Light.size() - 1; i++)
        {
            for (int j = 1; j < Light.size(); j++)
            {
                target temp(Light[i], Light[j]);
                
                if (temp.delta_k > 0.4)
                    continue;
                if (temp.dis_to_len_ratio < 0.7 || temp.dis_to_len_ratio > 1.25)
                    continue;

                Target.push_back(temp);
                //cout << temp.delta_k << endl;
                //cout << temp.dis_to_len_ratio << endl<<endl;
                Draw_Rect(src, temp.corner_point, Scalar(255, 0, 0));
            }
        }
     
        if (Target.size() != 0)
            success++;

    label:
        Light.clear();
        Target.clear();
  		contours.clear();
        temp.clear();
  
  		cv::imshow("src", src);
  
  	    double time = (double)(getTickCount() - t) / getTickFrequency();
  	    cout << "FPS:"<< 1/time<<endl;
        cout<<"success rate:"<<(double)success/all_1<<endl;
        if (all_1 == 30)
  	    {
  		    all_1 = 0;
  		    success = 0;
  	    }
     
  	    cout << "------------------------" << endl;
  	}
   
    return 0;
}

void Draw_Rect(Mat& img, Point2f* p, Scalar scalar)
{
	line(img, p[0], p[1], scalar, 2);
	line(img, p[1], p[2], scalar, 2);
	line(img, p[2], p[3], scalar, 2);
	line(img, p[3], p[0], scalar, 2);
}

void drawapp(Mat app, Mat img) {
	for (int i = 0; i < app.rows; i++) {
		if (i == app.rows - 1)
		{
			Vec2i point1 = app.at<Vec2i>(i);
			Vec2i point2 = app.at<Vec2i>(0);
			line(img, point1, point2, Scalar(255, 0, 0), 2, 8, 0);
			break;
		}
		Vec2i point1 = app.at<Vec2i>(i);
		Vec2i point2 = app.at<Vec2i>(i + 1);
		line(img, point1, point2, Scalar(255, 0, 0), 2, 8, 0);
	}
}

double count_dis(Point2f a, Point2f b) {
    double temp = (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y);
    temp = sqrt(temp);
    return temp;
}
void fillContours(Mat inputMat,int mode) {
    Mat dst;
    vector<Mat> temp;
    vector<vector<Point>> contours;

    split(inputMat, temp);

    if (mode)
    {
        dst = temp[0]*1.5;
        dst -= temp[2] * 0.5 + temp[1] * 0.5;
    }
    else
    {
        dst = temp[2] * 1.5;
        dst -= temp[0]*0.5 + temp[1] * 0.5;
    }

    threshold(dst, dst, 100, 255, THRESH_OTSU);
    findContours(dst, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);

    if (contours.size() == 0)
        return;
    drawContours(inputMat, contours, -1, Scalar(0, 0, 255), -1);
    imshow("1", inputMat);
}